package todo;


import se.lth.cs.realtime.*;
import done.AbstractWashingMachine;


public class WaterController extends PeriodicThread {
	AbstractWashingMachine mach;
	double speed;
	WashingProgram msgSource;
	int activeMode;
	double refLevel;

	public WaterController(AbstractWashingMachine mach, double speed) {
		super((long) (10000/speed));
		this.mach = mach;
		this.speed = speed;
	}

	public void perform() {
		WaterEvent msg = (WaterEvent) mailbox.tryFetch();
		if(msg != null){
			activeMode = msg.getMode();
			msgSource = (WashingProgram) msg.getSource();	// Save the source of the message
			switch(activeMode){
			case WaterEvent.WATER_DRAIN: 
				mach.setFill(false);						// Close water valve first
				mach.setDrain(true);						// Begin draining
				refLevel = msg.getLevel();
				break;
			case WaterEvent.WATER_FILL: 
				mach.setDrain(false); 						// Drain pump off first
				mach.setFill(true);							// Begin filling
				refLevel = msg.getLevel();
				break;
			case WaterEvent.WATER_IDLE: 					// Close everything, e.g. when interrupted
				mach.setDrain(false); 
				mach.setFill(false);
				break;
			}
		}
		
		switch(activeMode){
		case WaterEvent.WATER_DRAIN: 
			if(mach.getWaterLevel() <= refLevel/20){
				mach.setDrain(false);
				msgSource.putEvent(new AckEvent(this));
				activeMode = WaterEvent.WATER_IDLE;
			}
			break;
		case WaterEvent.WATER_FILL: 
			if(mach.getWaterLevel() >= (refLevel-this.getPeriod()*0.1*speed/1000.0)/20.0){
				mach.setFill(false);
				msgSource.putEvent(new AckEvent(this));
				activeMode = WaterEvent.WATER_IDLE;
			}
			break;
		case WaterEvent.WATER_IDLE:
			break;
		}
	}
}
